package com.fanx.redis.lock.spring.config;

import com.fanx.redis.lock.core.RedisLockImpl;
import com.fanx.redis.lock.core.RedisLockable;

import com.fanx.redis.lock.spring.annotation.RedisLock;
import com.fanx.redis.lock.spring.annotation.RedisLockMethodInterceptor;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * @author fanhang
 */
@Configuration
public class RedisLockAutoConfiguration {

	private final Logger log = LoggerFactory.getLogger(RedisLockAutoConfiguration.class);

	@Bean
	public RedisLockable redisLockable(RedisLockProperties props) {
		log.info("redis-lock-config: {}", props);
		Assert.notNull(props, "require [redis-lock]");
		Assert.hasLength(props.getHost(), "require [redis-lock.host]");

		RedisURI.create(props.getHost(), props.getPort());
		RedisURI.Builder builder = RedisURI.builder().withHost(props.getHost()).withPort(props.getPort())
				.withDatabase(props.getDatabase());
		if (StringUtils.hasLength(props.getPassword())) {
			builder.withPassword(props.getPassword());
		}
		RedisClient redisClient = RedisClient.create(builder.build());
		return new RedisLockImpl(redisClient);
	}

	@Bean
	public DefaultPointcutAdvisor defaultPointcutAdvisor(RedisLockable redisLockable) {
		RedisLockMethodInterceptor interceptor = new RedisLockMethodInterceptor(redisLockable);
		Pointcut pointcut = new AnnotationMatchingPointcut(Service.class, RedisLock.class, true);
		return new DefaultPointcutAdvisor(pointcut, interceptor);
	}

}
